<?php
/**
 * Created by PhpStorm.
 * User: Len
 * Date: 2019/12/7
 * Time: 15:55
 */

namespace app\task\controller;

use apollo\ApolloClient;
use think\Exception;
use think\facade\Env;

class Apollo {
    
    /**
     * @desc apollo集群env文件管理
     */
    public function start() {
        set_time_limit(0);
        
        $rootPath = Env::get('root_path');
        $runtimePath = Env::get('runtime_path');
    
        //生成env目录
        $envPath = $runtimePath . 'env'.DIRECTORY_SEPARATOR;
        !is_dir($envPath) && mkdir($envPath, 0755, true);
        
        $server     = Env::get('apollo.server');
        $appid      = Env::get('apollo.appid');
        $namespaces = Env::get('apollo.namespaces');
        $clientIp   = '';
        $cluster    = Env::get('apollo.cluster');
        
        echo 'rootPath:'.$rootPath."\n";
        echo 'runtimePath:'.$runtimePath."\n";
        
        //env模板文件
        define('APOLLO_ENV_TPL', $rootPath. '.env_tpl.php');
        
        //生成之后的.env文件路径
        define('APOLLO_ENV_FILE', $envPath . '.env');
        
        //定义apollo配置变更时的回调函数，动态异步更新.env
        $callback = function() use ($envPath) {
            $list   = glob($envPath. 'apolloConfig.*');
            $apollo = [];
            foreach($list as $l) {
                $config = require $l;
                if(is_array($config) && isset($config['configurations'])) {
                    $prefix                   = $config['namespaceName'];
                    $config['configurations'] = array_combine(array_map(function($key) use ($prefix) {
                        return $prefix . '.' . $key;
                    }, array_keys($config['configurations'])), $config['configurations']);
                    $apollo                   = array_merge($apollo, $config['configurations']);
                }
            }
            if(!$apollo) {
                throw new Exception('Load Apollo Config Failed, no config available');
            }
            ob_start();
            include APOLLO_ENV_TPL;
            $env_config = ob_get_contents();
            ob_end_clean();
            file_put_contents(APOLLO_ENV_FILE, $env_config);
        };

        $namespaces = explode(',', $namespaces);

        $apollo = new ApolloClient($server, $appid, $namespaces);
        $apollo->setCluster($cluster);

        //灰度发布暂时用不到
//        if($clientIp = getenv('CLIENTIP')) {
//            $apollo->setClientIp($this->clientIp);
//        }
        
        $apollo->save_dir = $envPath;
        ini_set('memory_limit', '128M');
        $pid = getmypid();
        echo "start [$pid]\n";
        $restart = true; //auto start if failed
        do {
            $error = $apollo->start($callback);
            if($error) echo('error:' . $error . "\n");
        } while($error && $restart);
    }

}

